﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;


public static class Gen
{
	/// <summary>
	/// 按位取反枚举
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="enumeration"></param>
	/// <returns></returns>
	public static T ReverseEnum<T>(T enumeration) where T : Enum
	{
		//直接对枚举使用~就可以了
		var b = (~(int)(object)enumeration);
        return (T)(object)(b);

    }

    public static T RandomEnumValue<T>(bool disallowFirstValue)
	{
		int min = (disallowFirstValue ? 1 : 0);
		T[] array = (T[])Enum.GetValues(typeof(T));
		int num = UnityEngine.Random.Range(min, array.Length);
		return array[num];
	}
	/// <summary>
	/// 所选所有枚举
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="value"></param>
	/// <returns></returns>
	public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
	{
		CultureInfo cult = CultureInfo.InvariantCulture;
		int valueAsInt = Convert.ToInt32(value, cult);
		foreach (object value2 in Enum.GetValues(typeof(T)))
		{
			int num = Convert.ToInt32(value2, cult);
			if (num == (valueAsInt & num))
			{
				yield return (T)value2;
			}
		}
	}
	/// <summary>
	/// 交换
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="x"></param>
	/// <param name="y"></param>
	public static void Swap<T>(ref T x, ref T y)
	{
		T val = y;
		y = x;
		x = val;
	}

	/// <summary>
	/// 固定Step更新
	/// </summary>
	/// <param name="timeBuffer"></param>
	/// <param name="fps"></param>
	/// <returns></returns>
	public static int FixedTimeStepUpdate(ref float timeBuffer, float fps)
	{
		timeBuffer += Mathf.Min(Time.deltaTime, 1f);
		float num = 1f / fps;
		int num2 = Mathf.FloorToInt(timeBuffer / num);
		timeBuffer -= (float)num2 * num;
		return num2;
	}

	public static int HashCombine<T>(int seed, T obj)
	{
		int num = obj?.GetHashCode() ?? 0;
		return (int)(seed ^ (num + 2654435769u + (seed << 6) + (seed >> 2)));
	}

	public static int HashCombineStruct<T>(int seed, T obj) where T : struct
	{
		return (int)(seed ^ (obj.GetHashCode() + 2654435769u + (seed << 6) + (seed >> 2)));
	}
	public static int HashCombineInt(int v1, int v2, int v3, int v4)
	{
		int num = 352654597;
		int num2 = num;
		num = ((num << 5) + num + (num >> 27)) ^ v1;
		num2 = ((num2 << 5) + num2 + (num2 >> 27)) ^ v2;
		num = ((num << 5) + num + (num >> 27)) ^ v3;
		num2 = ((num2 << 5) + num2 + (num2 >> 27)) ^ v4;
		return num + num2 * 1566083941;
	}


	public static int HashCombineInt(int seed, int value)
	{
		return (int)(seed ^ (value + 2654435769u + (seed << 6) + (seed >> 2)));
	}

	public static int HashOffset(this int baseInt)
	{
		return HashCombineInt(baseInt, 169495093);
	}

}

